import 'dart:async';

import 'package:flutter/services.dart';

class MeiQiaResult {
  int code;
  String message;
  Map<dynamic, dynamic> data;

  MeiQiaResult(this.code, this.message, this.data);

  @override
  String toString() {
    return 'MeiQiaResult{code: $code, message: $message, data: $data}';
  }
}

/// 美洽客户信息类
class ClientInfo {
  String name;
  String gender;
  String age;
  String tel;
  String qq;
  String weixin;
  String weibo;
  String address;
  String email;
  String avatar;
  String source;
  String comment;
  List<String> tags;
  Map<String, String> extras;

  ClientInfo({
    this.name = '', // 名字
    this.gender = '', // 性别
    this.age = '', // 年龄
    this.tel = '', // 电话
    this.qq = '', // QQ
    this.weixin = '', // 微信
    this.weibo = '', // 微博
    this.address = '', // 地址
    this.email = '', // 邮箱
    this.avatar = '', // 头像地址
    this.source = '', // 来源
    this.comment = '', // 备注
    this.tags, // 标签，数组形式，且必须是企业中已经存在的标签
    this.extras, // 一些额外的信息
  });
}

/// 预发送信息
class PreSendInfo {
  String message;
  String imagePath;

  PreSendInfo({
    this.message = '', // 预发送文字消息
    this.imagePath = '', // 预发送图片地址，本地图片地址
  });
}

class ConversionSettings {
  String clientId;
  String customizedId;
  String agentToken;
  String agentGroupToken;
  ClientInfo clientInfo;
  PreSendInfo preSendInfo;

  ConversionSettings({
    this.clientId, // 指定顾客 id 上线
    this.customizedId, // 开发者 id
    this.agentToken, // 指定客服 id 上线
    this.agentGroupToken, // 指定客服分组 id 上线
    this.clientInfo,
    this.preSendInfo,
  });
}

/// 美洽客服信息类
class MeiQiaAgentInfo {
  String avatar;
  String cellphone;
  String email;
  int enterpriseId;
  String id;
  int agentId;
  String nickname;
  String publicCellphone;
  String publicEmail;
  String qq;
  String realname;
  String signature;
  String status;
  String telephone;
  String weixin;
  bool isOnline;
  String privilege;

  static MeiQiaAgentInfo fromMap(Map<dynamic, dynamic> map) {
    var info = MeiQiaAgentInfo();
    info.avatar = map['avatar'];
    info.cellphone = map['cellphone'];
    info.email = map['email'];
    info.enterpriseId = map['enterprise_id'];
    info.id = map['id'];
    info.agentId = map['agentId'];
    info.nickname = map['nickname'];
    info.publicCellphone = map['public_cellphone'];
    info.publicEmail = map['public_email'];
    info.qq = map['qq'];
    info.realname = map['realname'];
    info.signature = map['signature'];
    info.status = map['status'];
    info.weixin = map['weixin'];
    info.isOnline = map['isOnline'];
    info.privilege = map['privilege'];
    return info;
  }

  @override
  String toString() {
    return 'MeiQiaAgentInfo{avatar: $avatar, cellphone: $cellphone, email: $email, enterpriseId: $enterpriseId, id: $id,'
        ' agentId: $agentId, nickname: $nickname, publicCellphone: $publicCellphone, publicEmail: $publicEmail, qq: $qq, realname: $realname, '
        'signature: $signature, status: $status, telephone: $telephone, weixin: $weixin, isOnline: $isOnline, privilege: $privilege}';
  }
}

class MeiQiaResultCode {
  static const CODE_SUCCEED = 1;
  static const CODE_FAILED = 2;
}

class MessageCode {
  static const OTHER_ACTION = 0xff00;
  static const MESSAGE_RECEIVER = 0xff01;
  static const AGENT_INPUTTING = 0xff02;
  static const AGENT_CHANGE = 0xff03;
}

class MeiQiaTitleGravity {
  static const GRAVITY_LEFT = 1;
  static const GRAVITY_CENTER = 2;
}

class FlutterMeiqia {
  static const MethodChannel _channel = const MethodChannel('flutter_meiqia');
  static const EventChannel _stream = const EventChannel('flutter_meiqia_event');

  /// 初始化美洽，样式定制目前只支持原生端资源调用
  static Future<MeiQiaResult> registerMeiQia(
    String meiqiaKey, {
    bool debugModel = true,
    int gravity = MeiQiaTitleGravity.GRAVITY_CENTER,
  }) async {
    var result = await _channel.invokeMethod<Map>(
      'registerMeiQia',
      {'key': meiqiaKey, 'debug': debugModel, 'gravity': gravity},
    );
    return MeiQiaResult(result['code'], result['message'], result['data']);
  }

  /// 开启美洽服务
  static Future openMeiQiaService() async {
    _channel.invokeMethod('openMeiQiaService');
  }

  /// 关闭美洽服务，适配 Android O，App 运行到后台的时候调用，
  /// 回到前台调用 [openMeiQiaService] 重新打开服务
  static Future closeMeiQiaService() async {
    _channel.invokeMethod('closeMeiQiaService');
  }

  /// 进入客服界面，具体配置查看 [ConversionSettings] 类
  /// 不传入 [ConversionSettings] 参数则进入默认会话界面
  /// agentToken, agentGroupToken 在控制台查询
  static Future conversation({ConversionSettings settings}) async {
    var params = Map<String, Object>();

    if (settings != null) {
      var clientInfo = settings.clientInfo;
      var preSendInfo = settings.preSendInfo;

      params['clientId'] = settings.clientId;
      params['customisedId'] = settings.customizedId;
      params['agentToken'] = settings.agentToken;
      params['groupToken'] = settings.agentGroupToken;

      if (clientInfo != null) {
        var tags = StringBuffer();

        if (clientInfo.tags != null) {
          clientInfo.tags.forEach((tag) {
            tags..write(tag)..write(',');
          });

          tags.toString().substring(0, tags.length - 1);
        }

        var clientParam = {
          'name': clientInfo.name,
          'gender': clientInfo.gender,
          'age': clientInfo.age,
          'tel': clientInfo.tel,
          'qq': clientInfo.qq,
          'weixin': clientInfo.weixin,
          'weibo': clientInfo.weibo,
          'address': clientInfo.address,
          'email': clientInfo.email,
          'avatar': clientInfo.avatar,
          'source': clientInfo.source,
          'comment': clientInfo.comment,
          'tags': tags.toString(),
          'extras': clientInfo.extras,
        };

        params['clientParams'] = clientParam;
      }

      if (preSendInfo != null) {
        params['preSend'] = {
          'message': preSendInfo.message,
          'image': preSendInfo.imagePath,
        };
      }
    }

    _channel.invokeMethod('conversation', params);
  }

  /// 进入留言界面
  static Future leaveMessage() async {
    _channel.invokeMethod('leaveMessage');
  }

  /// 获取新的 美洽 id
  static Future<String> getNewMeiQiaId() async {
    return await _channel.invokeMethod<String>('getNewMeiQiaId');
  }

  /// 设置顾客下线
  static Future<bool> setClientOffline() async {
    return await _channel.invokeMethod<bool>('setClientOffline');
  }

  /// 从服务器获取历史消息
  /// lastMessageTimeStamp 截止日期
  /// length 消息的长度
  /// fromService 从 service 或者 database 获取，默认 service 获取
  static Future<MeiQiaResult> getMQMessageFromServiceOrDatabase(
    int lastMessageTimeStamp,
    int length, {
    bool fromService = true,
  }) async {
    var result = await _channel.invokeMethod<Map>('getMQMessage', {
      'timeStamp': lastMessageTimeStamp,
      'length': length,
      'fromService': fromService,
    });
    return MeiQiaResult(result['code'], result['message'], result['data']);
  }

  /// 设置用户的设备唯一标识
  static Future<MeiQiaResult> registerDeviceToken(String token) async {
    var result = await _channel.invokeMethod<Map>('registerDeviceToken', {'token': token});
    return MeiQiaResult(result['code'], result['message'], result['data']);
  }

  /// 获取当前正在接待的客服信息
  /// data 如果非空可通过 [MeiQiaAgentInfo] 进行转换
  static Future<MeiQiaResult> getCurrentAgent() async {
    var result = await _channel.invokeMethod<Map>('getCurrentAgent');
    return MeiQiaResult(result['code'], result['message'], result['data']);
  }

  /// 获取当前顾客的 id
  static Future<String> getCurrentClientId() async {
    return await _channel.invokeMethod<String>('getCurrentClientId');
  }

  /// 获取一个新的顾客
  static Future<MeiQiaResult> createMQClient() async {
    var result = await _channel.invokeMethod<Map>('createMQClient');
    return MeiQiaResult(result['code'], result['message'], result['data']);
  }

  /// 更新消息阅读状态
  static Future updateMessage(int messageId, bool isRead) async {
    assert(messageId != null);
    assert(isRead != null);
    await _channel.invokeMethod('updateMessage', {'messageId': messageId, 'isRead': isRead});
  }

  /// 结束当前会话
  static Future<MeiQiaResult> endCurrentConversation() async {
    var result = await _channel.invokeMethod<Map>('endCurrentConversation');
    return MeiQiaResult(result['code'], result['message'], result['data']);
  }

  /// 切换当前顾客
  static Future<MeiQiaResult> setCurrentClient(String clientOrCustomizedId) async {
    var result = await _channel.invokeMethod<Map>('setCurrentClient', {'clientOrCustomizedId': clientOrCustomizedId});
    return MeiQiaResult(result['code'], result['message'], result['data']);
  }

  /// 读取未读消息
  /// clientIdOrCustomizedId 指定具体某个用户，空则全部
  static Future<MeiQiaResult> getUnreadMessages({String clientOrCustomizedId}) async {
    var result = await _channel.invokeMethod<Map>('setCurrentClient', {'clientOrCustomizedId': clientOrCustomizedId});
    return MeiQiaResult(result['code'], result['message'], result['data']);
  }

  /// 获取美洽 sdk 版本号
  static Future<String> getSdkVersion() async {
    return await _channel.invokeMethod<String>('getSdkVersion');
  }

  /// 监听消息变化
  static Stream<MeiQiaResult> messageListener() {
    return _stream.receiveBroadcastStream().map((result) {
      return MeiQiaResult(result['code'], result['message'], result['data']);
    });
  }
}
